package com.naiterui.ehp.bs.b2c.product.service.impl;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.naiterui.ehp.bp.bo.medication.MedicationDefaultUsageBO;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bs.b2c.product.entity.Medicine;
import com.naiterui.ehp.bs.b2c.product.entity.MedicineDefaultUsage;
import com.naiterui.ehp.bs.b2c.product.entity.Sku;
import com.naiterui.ehp.bs.b2c.product.repository.IMedicineDefaultUsageRepository;
import com.naiterui.ehp.bs.b2c.product.repository.IMedicineRepository;
import com.naiterui.ehp.bs.b2c.product.repository.ISkuRepository;
import com.naiterui.ehp.bs.b2c.product.service.IMedicineDefaultUsageService;

import cn.hutool.core.util.StrUtil;

@Service
public class MedicineDefaultUsageServiceImpl implements IMedicineDefaultUsageService {
    @Autowired
    private IMedicineDefaultUsageRepository medicineDefaultUsageRepository;
    @Autowired
    private ISkuRepository skuRepository;
    @Autowired
    private IMedicineRepository medicineRepository;

    @Override
    public Map<Long, MedicationDefaultUsageBO> findBySkuId(Set<Long> skuId) {
        List<MedicineDefaultUsage> usageList = this.medicineDefaultUsageRepository.findBySkuIdIn(skuId);
        List<Sku> skuList = this.skuRepository.findAllByIdIn(skuId);
        Map<Long, Sku> skuMap = skuList.stream().collect(Collectors.toMap(Sku::getId, s -> s));
        Set<Long> pIdSet = skuList.stream().map(Sku::getProductId).collect(Collectors.toSet());
        List<Medicine> medicineList = this.medicineRepository.findAllByProductIdIn(pIdSet);
        Map<Long, Medicine> medicineMap =
            medicineList.stream().collect(Collectors.toMap(Medicine::getProductId, m -> m));
        return usageList.stream()
            .map(medicineDefaultUsage -> {
                MedicationDefaultUsageBO medicationDefaultUsage = new MedicationDefaultUsageBO();
                BeanUtils.copyProperties(medicineDefaultUsage, medicationDefaultUsage);
                medicationDefaultUsage.setDosageStr(this.getJoiningDosage(medicineDefaultUsage));
                Sku sku = skuMap.get(medicineDefaultUsage.getSkuId());
                if (sku != null) {
                    Medicine medicine = medicineMap.get(sku.getProductId());
                    medicationDefaultUsage.setPackagSpec(sku.getPackingUnitNumber());
                    medicationDefaultUsage.setQuantityUnit(medicine.getPackingUnit());
                    medicationDefaultUsage.setEachDoseUnit(StrUtil.isBlank(medicineDefaultUsage.getEachDoseUnit())
                        ? medicine.getPackingUnitLimit() : medicineDefaultUsage.getEachDoseUnit());
                    medicationDefaultUsage.setMedicineMinUnit(medicine.getPackingUnitLimit());
                }
                return medicationDefaultUsage;
            }).collect(Collectors.toMap(MedicationDefaultUsageBO::getSkuId, Function.identity()));
    }

    @Override
    public MedicationDefaultUsageBO getBySkuId(Long skuId) {
        MedicineDefaultUsage medicineDefaultUsage = this.medicineDefaultUsageRepository.getBySkuId(skuId);
        if (medicineDefaultUsage == null) {
            return null;
        }
        Sku sku = this.skuRepository.get(skuId);
        Medicine medicine = this.medicineRepository.findByProductId(sku.getProductId());
        MedicationDefaultUsageBO medicationDefaultUsage = new MedicationDefaultUsageBO();
        BeanUtils.copyProperties(medicineDefaultUsage, medicationDefaultUsage);
        medicationDefaultUsage.setDosageStr(this.getJoiningDosage(medicineDefaultUsage));
        medicationDefaultUsage.setPackagSpec(sku.getPackingUnitNumber());
        medicationDefaultUsage.setQuantityUnit(medicine.getPackingUnit());
        return medicationDefaultUsage;
    }

    @Override
    public void insertOrUpdate(MedicationDefaultUsageBO medicationDefaultUsageBO) {
        Long skuId = medicationDefaultUsageBO.getSkuId();
        MedicineDefaultUsage medicineDefaultUsage = this.medicineDefaultUsageRepository.getBySkuId(skuId);
        // 新增
        if (null == medicineDefaultUsage) {
            medicineDefaultUsage = new MedicineDefaultUsage();
            BeanUtil.copyProperties(medicationDefaultUsageBO, medicineDefaultUsage);
            medicineDefaultUsage.setCreatedAt(new Date());
            medicineDefaultUsage.setCreatedBy("admin");
            medicineDefaultUsage.setChangedAt(new Date());
            medicineDefaultUsage.setChangedBy("admin");
            this.medicineDefaultUsageRepository.save(medicineDefaultUsage);
        } else {
            BeanUtil.copyProperties(medicationDefaultUsageBO, medicineDefaultUsage);
            medicineDefaultUsage.setChangedAt(new Date());
            medicineDefaultUsage.setChangedBy("admin");
            this.medicineDefaultUsageRepository.update(medicineDefaultUsage);
        }
    }

    private String getJoiningDosage(MedicineDefaultUsage medicineDefaultUsage) {
        if (medicineDefaultUsage.getDosageCycle() == null || medicineDefaultUsage.getDosageCount() == null
            || StrUtil.isBlank(medicineDefaultUsage.getDosageCycleUnit())) {
            return "";
        }
        DecimalFormat df = new DecimalFormat("##.##");
        String dosageCycleStr = df.format(medicineDefaultUsage.getDosageCycle());
        return "每" +
                ("1".equals(dosageCycleStr) ? "" : dosageCycleStr) +
                medicineDefaultUsage.getDosageCycleUnit() +
                medicineDefaultUsage.getDosageCount() +
                "次";
    }
}
